#include "BrokerServantImp.h"
#include "servant/Application.h"
#include "gamoosim.h"
#include "ptcldefine.h"
#include "log.h"
#include "LongLinkManager.h"

using namespace std;

extern BrokerServer g_app;


//////////////////////////////////////////////////////
void BrokerServantImp::initialize()
{
    //initialize servant here:
    std::string myConfFile = ServerConfig::BasePath+Toon::MYCONF;
    
    TC_Config myConf;
    myConf.parseFile(myConfFile);
    
  
    std::vector<std::string> vList = myConf.getDomainVector("/gamoos/servermap");
    for (auto strItem : vList){
        std::string keypath = "/gamoos/servermap/" + strItem;
        std::string strType = myConf.get(keypath+"<type>");
        DEBUG("keypath:" << keypath<<"  value:"<<strType);
        vector<std::string> vctType = Toon::string_split(strType, ',');
        std::string serverName = myConf.get(keypath+"<name>");
        if (serverName.empty()){
            ERROR("servername empty:"<<keypath);
            continue;
        }
        
        for (auto strType : vctType){
            if (strType.empty()){
                continue;
            }
            
            int type = TC_Common::strto<int>(strType);
            _mapServerName[type] = serverName;
            LOG_DEBUG("type:" << type<<"  serverName:"<<serverName);
        }
    }
 

 
}

//////////////////////////////////////////////////////
void BrokerServantImp::destroy()
{
    //destroy servant here:
    //...
}
//10 PING  心跳
//11 LOGIN 登录
//12 LOGOUT  登出
//13 KICKOUT 踢出
//14 MSG_SINGLE 单聊消息
//15 MSG_GROUP 群聊消息
//16 MSG_NOTIFY 业务通知消息
//17 MSG_CTRL  消息控制指令（比如撤销，删除等）
//18 MSG_READ  消息已读
//19 GET_HOTSESSION  热会话
//20 GET_HISTORY_MSG  历史消息
//21 GET_PRIORITY_MSG  高优先级消息
//22 SUBCRIBE_SESSION  订阅会话（订阅会话后，可以收到响应会话的消息）
//23 UNSUBCRIBE_SESSION  取消订阅会话
//24 SYNC_DATA 数据同步
int BrokerServantImp::doRequest(tars::TarsCurrentPtr current, vector<char>& response)
{
    //Return to the data package requested by the client itself, that is, the original package return (4-byte length + 4-byte request + buffer)
    try {
        const vector<char>& request = current->getRequestBuffer();
        
        gamoosim::ABCPack pack;
        unpackTars<gamoosim::ABCPack>(request, pack);
        pack.display(LOG->debug());
        
        //get the context;
        gamoosim::ClientContext context;
        LongLinkManager::getInstance()->(current->getUId(), context);
        DEBUG("uid:"<<current->getUId()<<" context:"<<context.writeToJsonString()<<" pack type:"<<pack.writeToJsonString());
        
        switch (pack.type) {
            case gamoosim::PING:
                this->processPingReq(current, context, pack);
                
                break;
            case gamoosim::LOGIN:
                this->processLoginReq(current, context, pack);
                break;
            case gamoosim::KICKOUT:
                this->processKickoutReq(current, context, pack);
                
                break;
            default:
                this->processReqRPC(current, context, pack);
                break;
        }
    } catch (exception ex) {
        ERROR("exception occur uid:"<<current->getUId()<<" ex:"<<ex.what());
        current->close();
    }
    
    return 0;
}

int BrokerServantImp::doClose(TarsCurrentPtr current)
{
    DEBUG("close ip: " << current->getIp()<<" uid:"<<current->getUId());

    return 0;
}


void BrokerServantImp::processReqRPC(tars::TarsCurrentPtr current, const Toon::ClientContext &context, const gamoosim::ABCPack &req)
{
    try
    {
        auto iter = _mapServerName.find(type);
        if (iter == _mapServerName.end()){
            ERROR("serverName empty, type can't support:" << type <<" clientId:"<<clientInfo.client_id);
            return;
        }
        
        std::string serverName = iter->second;
        
        DEBUG("type:"<<gamoosim::etos((gamoosim::MSG_TYPE)pack.type) << "("  << type << ")" <<" server:"<<serverName<<" clinetId:"<<clientInfo.clientId);
        
        CommonServantPrx proxy;
        Application::getCommunicator()->stringToProxy(serverName, proxy);
        tars::TC_AutoPtr<CommonServantPrxBrokerCallback> cb = new CommonServantPrxBrokerCallback(current, context, req);
        
        proxy->async_request(cb, context, req);
    }
    catch (std::exception& e)
    {
        ERROR("async_request error:" << e.what());
    }
    catch (...)
    {
        ERROR("async_request unknown exception");
    }
}

//void sendDataToClient(tars::TarsCurrentPtr current, const gamoosim::ABCPack &resp)
//{
//    if (current == nullptr)
//    {
//        ERROR("current is null!");
//        return;
//    }
//
//    std::vector<char> data;
//    packTars<gamoosim::ABCPack>(req, data);
//    DEBUG("pack type:"<<pack.writeToJsonString());
//    current->sendResponse(data.data(), data.size());
//}

void BrokerServantImp::processPingReq(tars::TarsCurrentPtr current, const Toon::ClientContext &context, const gamoosim::ABCPack &req)
{
    DEBUG("ping Req:"<<req.writeToJsonString());
 
    g_app.sendDataToClient(current, req);
}

void BrokerServantImp::processLoginReq(tars::TarsCurrentPtr current, const Toon::ClientContext &context, const gamoosim::ABCPack &req)
{
    
}

void BrokerServantImp::processKickoutReq(tars::TarsCurrentPtr current, const Toon::ClientContext &context, const gamoosim::ABCPack &req)
{
    
}

void BrokerServantImp::processLogoutReq(tars::TarsCurrentPtr current, const Toon::ClientContext &context, const gamoosim::ABCPack &req)
{
    
}


